package se.sll.service.catalogue.composite.helper.service;

import se.sll.service.catalogue.composite.camel.processor.HsaCallback;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import lombok.extern.slf4j.Slf4j;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import se.sll.service.catalogue.composite.camel.helper.HSAProcessor;
import se.sll.service.catalogue.common.rest.response.HsaData;

/**
 *
 * @author khaleddaham
 */
@Singleton
@Startup
@Slf4j
@SuppressWarnings("unchecked")
public class HsaCache {

    private final static CamelContext camelContext = new DefaultCamelContext();
    private final HsaCallback callback = new HsaCallback();

    public HsaCache() {
    }

    /**
     * @TODO Change the HSAProcessor to index on hsaId to speed up retrieval.
     */
    @PostConstruct
    public void initCache() {
        log.info("Started HsaCache.");
        try {
            camelContext.addRoutes(new RouteBuilder() {
                @Override
                public void configure() {
                    from("direct:start:hsacache")
                            .setHeader(Exchange.HTTP_URI, constant("http://api.offentligdata.minavardkontakter.se/orgmaster-hsa/v1/hsaObjects/"))
                            .setHeader(Exchange.HTTP_METHOD, constant("GET"))
                            .setHeader(Exchange.CONTENT_TYPE, constant("application/json; charset=UTF-8"))
                            .setHeader(Exchange.ACCEPT_CONTENT_TYPE, constant("application/json; charset=UTF-8"))
                            .to("http4://uri")
                            .bean(new HSAProcessor(), "hsaListResponseJSON")
                            .log("HsaCache finished loading.");
                }
            });
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
        try {
            camelContext.start();
            ProducerTemplate template = camelContext.createProducerTemplate();
            //hsaDataCache = (List<HsaData>) template.sendBody("direct:start:hsacache", ExchangePattern.InOut, "");
            
            template.asyncCallbackRequestBody("direct:start:hsacache", null, callback);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }

    @PreDestroy
    public void stop() throws Exception {
        log.info("Stopping HSA cache.");
        camelContext.stop();
    }

    /**
     * Search hsa cache by hsaId, if found return object, if not return null;
     * @param hsaId
     * @return HsaData
     */
    public HsaData getHsa(String hsaId) {
        for (HsaData h : callback.getData()) {
            if (h.getHsaId().equals(hsaId)) {
                return h;
            }
        }
        return getCacheMiss(hsaId);
    }

    /**
     * 
     * @param pattern
     * @return 
     */
    public List<String> findHsaIdByRDN(String pattern) {
        List<String> response = new ArrayList<>();
        for (HsaData h : callback.getData()) {
            if (h.getRelativeDistinguishedName().toLowerCase().contains(pattern.toLowerCase())) {
                response.add(h.getHsaId());
            }
        }
        return response;
    }

    /**
     * @TODO try against HSA if not found in our cache.
     * @param hsaId
     * @return
     */
    private HsaData getCacheMiss(String hsaId) {
        return null;
    }
}
